package com.wqnmdb.im.service.redis;

import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisConnectionUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.concurrent.TimeUnit;

@Service
public class RedisPoolService implements Serializable {

    @Autowired
    private StringRedisTemplate stringPoolRedisTemplate;

    public boolean set(final String key, final String value) {
        try {
            return stringPoolRedisTemplate.execute((RedisCallback<Boolean>) connection -> {
                RedisSerializer<String> serializer = stringPoolRedisTemplate.getStringSerializer();
                connection.set(serializer.serialize(key), serializer.serialize(value));
                return true;
            });
        }catch (Exception e) {
            RedisConnectionUtils.unbindConnection(stringPoolRedisTemplate.getConnectionFactory());
            return false;
        }finally {
            RedisConnectionUtils.unbindConnection(stringPoolRedisTemplate.getConnectionFactory());
        }
    }

    public boolean set(final String key, final String value, long expire) {
        try {
            set(key, value);
            return expire(key, expire);
        }catch (Exception e) {
            RedisConnectionUtils.unbindConnection(stringPoolRedisTemplate.getConnectionFactory());
            return false;
        }finally {
            RedisConnectionUtils.unbindConnection(stringPoolRedisTemplate.getConnectionFactory());
        }
    }
    public Boolean exists(final String key) {
        try {
            return stringPoolRedisTemplate.execute((RedisCallback<Boolean>) connection -> {
                RedisSerializer<String> serializer = stringPoolRedisTemplate.getStringSerializer();
                Boolean value = connection.exists(serializer.serialize(key));
                return value;
            });
        } catch (Exception e) {
            RedisConnectionUtils.unbindConnection(stringPoolRedisTemplate.getConnectionFactory());
            return false;
        }finally {
            RedisConnectionUtils.unbindConnection(stringPoolRedisTemplate.getConnectionFactory());
        }
    }
    public Boolean setnx(final String key,String value) {
        try {
            return stringPoolRedisTemplate.execute((RedisCallback<Boolean>) connection -> {
                RedisSerializer<String> serializer = stringPoolRedisTemplate.getStringSerializer();
                Boolean aBoolean = connection.setNX(serializer.serialize(key), serializer.serialize(value));
                return aBoolean;
            });
        } catch (Exception e) {
            RedisConnectionUtils.unbindConnection(stringPoolRedisTemplate.getConnectionFactory());
            return false;
        }finally {
            RedisConnectionUtils.unbindConnection(stringPoolRedisTemplate.getConnectionFactory());
        }
    }
    public String get(final String key) {
        try {
            return stringPoolRedisTemplate.execute((RedisCallback<String>) connection -> {
                RedisSerializer<String> serializer = stringPoolRedisTemplate.getStringSerializer();
                byte[] value = connection.get(serializer.serialize(key));
                return serializer.deserialize(value);
            });
        } catch (Exception e) {
            RedisConnectionUtils.unbindConnection(stringPoolRedisTemplate.getConnectionFactory());
            return null;
        }finally {
            RedisConnectionUtils.unbindConnection(stringPoolRedisTemplate.getConnectionFactory());
        }
    }
    public boolean expire(final String key, long expire) {
        try {
            return stringPoolRedisTemplate.expire(key, expire, TimeUnit.SECONDS);

        }catch (Exception e){
            RedisConnectionUtils.unbindConnection(stringPoolRedisTemplate.getConnectionFactory());
            return false;
        }finally {
            RedisConnectionUtils.unbindConnection(stringPoolRedisTemplate.getConnectionFactory());
        }
    }

    public long lpush(final String key, Object obj) {
        final String value = JSON.toJSON(obj).toString();
        try {
            return stringPoolRedisTemplate.execute((RedisCallback<Long>) connection -> {
                RedisSerializer<String> serializer = stringPoolRedisTemplate.getStringSerializer();
                return connection.lPush(serializer.serialize(key), serializer.serialize(value));
            });
        }catch (Exception e){
            RedisConnectionUtils.unbindConnection(stringPoolRedisTemplate.getConnectionFactory());
            return 0;
        }finally {
            RedisConnectionUtils.unbindConnection(stringPoolRedisTemplate.getConnectionFactory());
        }
    }

    public long rpush(final String key, Object obj) {
        try {
            final String value = JSON.toJSON(obj).toString();
            return stringPoolRedisTemplate.execute((RedisCallback<Long>) connection -> {
                RedisSerializer<String> serializer = stringPoolRedisTemplate.getStringSerializer();
                return (long) connection.rPush(serializer.serialize(key), serializer.serialize(value));
            });
        }catch (Exception e){
            RedisConnectionUtils.unbindConnection(stringPoolRedisTemplate.getConnectionFactory());
            return Long.valueOf(0);
        }finally {
            RedisConnectionUtils.unbindConnection(stringPoolRedisTemplate.getConnectionFactory());
        }
    }

    public String lpop(final String key) {
        try {
            return stringPoolRedisTemplate.execute((RedisCallback<String>) connection -> {
                RedisSerializer<String> serializer = stringPoolRedisTemplate.getStringSerializer();
                byte[] res = connection.lPop(serializer.serialize(key));
                return serializer.deserialize(res);
            });
        }catch (Exception e){
            RedisConnectionUtils.unbindConnection(stringPoolRedisTemplate.getConnectionFactory());
            return null;
        }finally {
            RedisConnectionUtils.unbindConnection(stringPoolRedisTemplate.getConnectionFactory());
        }
    }
    public String rpop(String key) {
        try {
            return stringPoolRedisTemplate.execute((RedisCallback<String>) connection -> {
                RedisSerializer<String> serializer = stringPoolRedisTemplate.getStringSerializer();
                byte[] res = connection.rPop(serializer.serialize(key));
                return serializer.deserialize(res);
            });
        }catch (Exception e){
            RedisConnectionUtils.unbindConnection(stringPoolRedisTemplate.getConnectionFactory());
            return null;
        }finally {
            RedisConnectionUtils.unbindConnection(stringPoolRedisTemplate.getConnectionFactory());
        }
    }

    public Long incr(String key, long growthLength) {
        try {
            return stringPoolRedisTemplate.opsForValue().increment(key, growthLength);
        }catch (Exception e){
            RedisConnectionUtils.unbindConnection(stringPoolRedisTemplate.getConnectionFactory());
            return Long.valueOf(0);
        }finally {
            RedisConnectionUtils.unbindConnection(stringPoolRedisTemplate.getConnectionFactory());
        }
    }

    public boolean del(String key) {
        try {
            return stringPoolRedisTemplate.execute((RedisCallback<Boolean>) connection -> {
                RedisSerializer<String> serializer = stringPoolRedisTemplate.getStringSerializer();
                connection.del(serializer.serialize(key));
                return true;
            });
        }catch (Exception e){
            RedisConnectionUtils.unbindConnection(stringPoolRedisTemplate.getConnectionFactory());
            return false;
        }finally {
            RedisConnectionUtils.unbindConnection(stringPoolRedisTemplate.getConnectionFactory());
        }
    }
    public boolean put(String key, String attribute, String value) {
        try {
            return stringPoolRedisTemplate.execute((RedisCallback<Boolean>) connection -> {
                RedisSerializer<String> serializer = stringPoolRedisTemplate.getStringSerializer();
                connection.hSet(serializer.serialize(key), serializer.serialize(attribute), serializer.serialize(value));
                return true;
            });
        }catch (Exception e){
            RedisConnectionUtils.unbindConnection(stringPoolRedisTemplate.getConnectionFactory());
            return false;
        }finally {
            RedisConnectionUtils.unbindConnection(stringPoolRedisTemplate.getConnectionFactory());
        }

    }
    public String getH(String key, String attribute) {
        try {
            return stringPoolRedisTemplate.execute((RedisCallback<String>) connection -> {
                RedisSerializer<String> serializer = stringPoolRedisTemplate.getStringSerializer();
                byte[] value = connection.hGet(serializer.serialize(key), serializer.serialize(attribute));
                return serializer.deserialize(value);
            });
        } catch (Exception e) {
            RedisConnectionUtils.unbindConnection(stringPoolRedisTemplate.getConnectionFactory());
            return null;
        }finally {
            RedisConnectionUtils.unbindConnection(stringPoolRedisTemplate.getConnectionFactory());
        }
    }

}
